package com.gitee.cui.lock.custom;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 自定义简单版本独占锁实现
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021/11/29 13:24
 **/
public class SimpleMockLock implements Lock {

    private Sync sync = new Sync();

    /**
     * 静态内部类，实际加锁与释放操作的实现类
     * state为1，表示已经获得锁
     * state为0，表示没有加锁
     */
    public static class Sync extends AbstractQueuedSynchronizer {
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            // 当前线程不是持有锁的线程
            if (Thread.currentThread() != getExclusiveOwnerThread()) {
                throw new IllegalMonitorStateException();
            }

            // 当前状态不是已经加锁的状态
            if (0 == getState()) {
                throw new IllegalMonitorStateException();
            }

            // 后面的操作都不需要加锁执行
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
    }

    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        throw new IllegalStateException("方法 lockInterruptibly 尚未实现");
    }

    @Override
    public boolean tryLock() {
        throw new IllegalStateException("方法 tryLock 尚未实现");
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        throw new IllegalStateException("方法 tryLock 尚未实现");
    }

    @Override
    public void unlock() {
        sync.release(0);
    }

    @Override
    public Condition newCondition() {
        throw new IllegalStateException("方法 newCondition 尚未实现");
    }
}
